package com.grj.parking.aaa;

import com.grj.parking.domain.ParkingLot;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsRequest;
import org.elasticsearch.action.admin.indices.exists.indices.IndicesExistsResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.client.ElasticsearchClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ElasticsearchService {

    private final RestHighLevelClient esClient;
    private static final String INDEX_NAME = "parking_lot";

    @Autowired
    public ElasticsearchService(RestHighLevelClient esClient) {
        this.esClient = esClient;
    }



    /**
     * 批量同步停车场数据到ES
     */
    public boolean bulkSync(List<ParkingLot> parkingLots) throws Exception {
        if (parkingLots.isEmpty()) {
            return true;
        }

        BulkRequest request = new BulkRequest();

        for (ParkingLot lot : parkingLots) {
            IndexRequest indexRequest = new IndexRequest(INDEX_NAME)
                    .id(lot.getId().toString())
                    .source(lot.toEsDocument());
            request.add(indexRequest);
        }

        BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);

        if (response.hasFailures()) {
            for (BulkItemResponse item : response.getItems()) {
                if (item.isFailed()) {
                    System.err.println("同步失败: " + item.getId() + ", 原因: " + item.getFailureMessage());
                }
            }
            return false;
        }

        return true;
    }

    /**
     * 搜索附近的停车场
     */
    public List<ParkingLot> searchNearby(double latitude, double longitude, double distance, int pageNum, int pageSize) throws IOException {
        // 参数校验
        if (pageNum <= 0 || pageSize <= 0) {
            throw new IllegalArgumentException("pageNum and pageSize must be positive integers.");
        }

        SearchRequest searchRequest = new SearchRequest(INDEX_NAME);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        // 构建查询条件
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();

        // 地理位置查询 - 圆形范围
        boolQuery.filter(QueryBuilders.geoDistanceQuery("location")
                .point(latitude, longitude)
                .distance(distance, DistanceUnit.METERS));

//        // 租户ID过滤
//        if (tenantId != null) {
//            boolQuery.filter(QueryBuilders.termQuery("tenantId", tenantId));
//        }
//
//        // 状态过滤
//        if (status != null) {
//            boolQuery.filter(QueryBuilders.termQuery("status", status));
//        }

        sourceBuilder.query(boolQuery);

        // 按距离排序
        sourceBuilder.sort(new GeoDistanceSortBuilder("location", latitude, longitude)
                .order(SortOrder.ASC)
                .unit(DistanceUnit.METERS));

        // 分页
        sourceBuilder.from((pageNum - 1) * pageSize);
        sourceBuilder.size(pageSize);

        searchRequest.source(sourceBuilder);

        // 执行查询
        SearchResponse response;
        try {
            response = esClient.search(searchRequest, RequestOptions.DEFAULT);
            System.out.println( response);
        } catch (Exception e) {
            throw new IOException("Elasticsearch search failed", e);
        }

        // 处理结果
        List<ParkingLot> result = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {
            Map<String, Object> sourceMap = hit.getSourceAsMap();
            // 修复类型转换问题：Map -> JSON String -> ParkingLot
            String jsonString = JSON.toJSONString(sourceMap);
            ParkingLot lot = JSON.parseObject(jsonString, ParkingLot.class);

            // 设置距离
            lot.setDistance((Double) hit.getSortValues()[0]);
            result.add(lot);
        }

        return result;
    }


    /**
     * 删除ES中的文档
     */
    public boolean deleteDocument(Long id) throws IOException {
        DeleteRequest request = new DeleteRequest(INDEX_NAME, id.toString());
        esClient.delete(request, RequestOptions.DEFAULT);
        return true;
    }
}
